#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <malloc.h>
#include <sstream>
#include "Debug.h"
#include "sockConn.h"
using namespace mayi;
using namespace std;

bool sockConn::Connect( )
{
        m_lCurtime = time(NULL);
	if(m_socket == 0)
	{
		struct hostent *he;
		struct sockaddr_in their_addr;
		he = gethostbyname(m_sHostname.c_str());
		if((m_socket = socket(AF_INET,SOCK_STREAM,0))==-1)
		{
			perror("socketi error!");
                        m_bLive = false;
                        m_socket = 0;
			return false;
		}
		their_addr.sin_family = AF_INET;
		their_addr.sin_port = htons( m_iPort );
		their_addr.sin_addr = *((struct in_addr *)he->h_addr);
		bzero(&(their_addr.sin_zero), 8);
		if(connect(m_socket, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) ==-1){
			perror("connect error!");
			close(m_socket);
			m_socket = 0;
			m_bLive = false;
			return false;
		}
	}  
	m_bLive = true;
	return m_bLive;
}


void sockConn:: Print()
{
	cout<<"service = "<< m_sHostname.c_str()<<endl;;
	cout<<"port = "<< m_iPort<<"\n";
	cout<<"last = "<< m_lLasttime<<"\n";
	m_bLive ? cout<<"bLive = true\n" : cout<< "bLive = false\n";
	cout<<"key = "<< m_iKey << "\n";
	cout<<"backup = "<< m_iBackup << endl;
} 
void sockConn:: disConnect()
{
        DEBUG1(" ----------- ");
	if(m_socket != 0)
	{
		cout<<" close "<< m_sHostname.c_str()<<":"<<m_iPort <<endl;
                close(m_socket);
		m_socket  = 0;
		m_lLasttime = time(NULL);
		m_bLive = false;
	}
	else
		m_bLive = false;
}

int sockConn:: Proxy(const char *data, unsigned dlen, char **wbuf, unsigned &wsize, unsigned &wbytes)
{
        if(*wbuf == NULL || wsize == 0 )
        {
            wsize = 1024;
            *wbuf = (char *)malloc( wsize );
            if(*wbuf == NULL)
            {
                  wsize = 0;
                  return -4;
            }
        }
	if(send(m_socket, data, dlen, 0) ==-1) {
		perror("send");
		disConnect();                
		return -1;
	}
	int readlen = 0;
	int blen = wsize;
	if((readlen = recv(m_socket, *wbuf, wsize, 0))> 0)
	{
		if(readlen < (int)wsize)
		{
                        *((*wbuf)+readlen) = '\0'; 
			wbytes = readlen;
			return 0;
		}
		while( readlen == blen)
		{
			char buf[ blen +1 ];
			wsize += blen;
			*wbuf = (char *)realloc(*wbuf,  wsize);
			if(wbuf != NULL)
			{
				readlen = recv(m_socket, buf, blen, 0);
				if(readlen > 0)
				{
					buf[readlen] = '\0';
					bcopy(buf, *wbuf+wbytes, readlen);
                                        wbytes += readlen;
				} 
				else
					break;   
			}            
			else
			{
                                wbytes = 0;
				disConnect();
				return -3;
			}
		}
                return 0;
	}
        perror("recv");
	disConnect();
	return -2;
}

